package com.example.common.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 *
 * @author cui haida
 * @version JDK 8
 * 2025/8/4
 */
@Component
public class JwtUtils {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration;

    /**
     * 获取密钥
     */
    private SecretKey getSecretKey() {
        return Keys.hmacShaKeyFor(secret.getBytes());
    }

    /**
     * 生成JWT令牌
     * @param subject 主题 - 用户名
     * @param claims 自定义信息 - KV键值对
     */
    public String generateToken(String subject, Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims) // 添加自定义信息
                .setSubject(subject) // 添加主题
                .setIssuedAt(new Date()) // 添加签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration)) // 添加过期时间
                .signWith(getSecretKey()) // 添加密钥
                .compact(); // 生成对应的JWT令牌字符串
    }

    /**
     * 解析JWT令牌，返回Claims对象
     * 可以通过Claims对象获取自定义信息，claims.get("自定义信息")
     */
    public Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSecretKey()) // 设置密钥
                .build()
                .parseClaimsJws(token) // 解析JWT令牌
                .getBody(); // 获取自定义信息
    }

    /**
     * 判断令牌是否过期
     */
    public boolean isTokenExpired(String token) {
        // 获取令牌中的过期时间
        Claims claims = parseToken(token);
        Date expiration = claims.getExpiration();
        // 判断是否过期
        return expiration.before(new Date());
    }

    public String getUsernameFromToken(String token) {
        return parseToken(token).getSubject();
    }

    public boolean validateToken(String jwt) {
        return !isTokenExpired(jwt);
    }
}